package org.zzh.config;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.zzh.shiro.MyRealm;

import java.util.LinkedHashMap;
import java.util.Map;


@Configuration
public class ShiroConfig {

    /**
     * 创建并配置Shiro过滤器工厂豆
     * <p>
     * 该方法主要用于配置Shiro过滤器，设置安全管理器，以及定义过滤链
     * 过滤链的配置决定了哪些URL需要进行身份验证，哪些可以匿名访问
     *
     * @return ShiroFilterFactoryBean实例，用于配置Shiro过滤器
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilter() {
        // 创建Shiro过滤器工厂豆实例
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        // 设置安全管理器，负责实际的安全管理工作
        shiroFilterFactoryBean.setSecurityManager(securityManager());

        // 配置登录页面和未授权页面的URL
        shiroFilterFactoryBean.setLoginUrl("/toLogin.do");
        shiroFilterFactoryBean.setUnauthorizedUrl("/toUnauthorized");

        // 配置过滤链
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        // 配置允许匿名访问的URL
        filterChainDefinitionMap.put("/login.do", "anon");
        filterChainDefinitionMap.put("/logout", "logout");
        filterChainDefinitionMap.put("/toLogin.do", "anon");
        filterChainDefinitionMap.put("/register", "anon");
        filterChainDefinitionMap.put("/**", "authc");

        // 将过滤链定义设置到Shiro过滤器工厂豆中
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        // 返回配置好的Shiro过滤器工厂豆实例
        return shiroFilterFactoryBean;
    }

    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(authReaml());
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        // 启用会话验证
        sessionManager.setSessionValidationSchedulerEnabled(true);
        // 禁用 URL 重写
        sessionManager.setSessionIdUrlRewritingEnabled(false);
        // 配置 SessionManager
        securityManager.setSessionManager(sessionManager);
        SecurityUtils.setSecurityManager(securityManager);
        return securityManager;
    }

    @Bean
    public MyRealm authReaml() {
        MyRealm authReaml = new MyRealm();
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        matcher.setHashAlgorithmName("MD5");
        authReaml.setCredentialsMatcher(matcher);
        return authReaml;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager());
        return advisor;
    }


    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }

}